# import asyncio
#
#
# import redis
# import websockets
# import json
# import hashlib
# from fastapi import Depends
#
# from core.config import settings
# from core.logger import log
# from datetime import datetime
# from services.wx_friends_service import get_specified_friends
# from utils.llm_api import DeepSeekClient
#
# from utils.sender_tools import SenderTools
# from services.wx_chat_messages import create_wx_messages, get_wx_messages
# from services.redis_service import AsyncRedisService
#
#
# class WebSocketService:
#     def __init__(self, TOKEN_KEY: str):
#         self.ws_url = f"ws://{settings.BASE_IP}:{settings.BASE_PORT}/ws/GetSyncMsg"
#         self.api_key = TOKEN_KEY
#         self.websocket_conn = None
#         self.is_running = False
#         self.DeepSeekAPI = DeepSeekClient()
#         self.sender_tools = SenderTools()
#         self.redis_service= AsyncRedisService()
#         self.redis_client = None
#         self.Reconnect_Count = 0
#         self.timt_num = 20
#
#
#     async def on_message(self, message):
#         try:
#             data = json.loads(message)
#             log.info(f"收到消息: {message}")
#             formatted_message = self.format_message(data)
#             #获取客户名单：
#             customer_wx_id_list = await get_specified_friends("客户",formatted_message["接收者"])
#             log.info(f"客户名单: {customer_wx_id_list}")
#             if formatted_message["发送者"] in customer_wx_id_list:
#                 log.info(f"是需要回复的用户，原始消息内容: {message}")
#                 # 生成唯一id(接收者，发送者，消息内容);
#                 msg_fingerprint = hashlib.sha256(
#                     f"{formatted_message['发送者']}:"
#                     f"{formatted_message['接收者']}:"
#                     f"{formatted_message['原始内容']}".encode()
#                 ).hexdigest()
#                 redis_key = f"msg_fingerprint:{msg_fingerprint}"
#
#                 is_new = await self.redis_client.set(
#                     name=redis_key,
#                     value=1,
#                     ex=60 * 60 * 24 * 1,  # 1天
#                     nx=True
#                 )
#                 # 如果是重复消息则跳过
#                 if is_new is None:  # set命令返回None表示键已存在
#                     log.info(f"跳过重复消息: {formatted_message['原始内容']}...")
#                     return
#                 # 保存接受消息到数据库
#                 await create_wx_messages(formatted_message["发送者"], formatted_message["接收者"], "接收", formatted_message["原始内容"])
#
#                 # 开始回复
#                 chat_message = formatted_message["原始内容"]
#
#                 message_list = await get_wx_messages()  # 异步获取历史消息
#                 #判断是不是第一次对话
#                 if len(message_list) == 1:
#                     reply = await self.DeepSeekAPI.get_reply(chat_message, "", formatted_message["发送者"])
#                     # 发送消息
#                     send = self.sender_tools.send_wx_message(reply, formatted_message["发送者"], self.api_key)
#                     log.info(f"发送结果: {send}")
#                     await create_wx_messages(formatted_message["发送者"], formatted_message["接收者"], "回复", reply)
#                 elif len(message_list) > 1:
#                     reply = await self.DeepSeekAPI.get_reply_with_history(message_list, "", formatted_message["发送者"])
#                     # 发送消息
#                     send = self.sender_tools.send_wx_message(reply, formatted_message["发送者"], self.api_key)
#                     log.info(f"发送结果: {send}")
#                     await create_wx_messages(formatted_message["发送者"], formatted_message["接收者"], "回复", reply)
#         except redis.RedisError as e:
#             log.error(f"Redis 操作出错: {str(e)}")
#         except Exception as e:
#             log.error(f"处理消息时出错: {str(e)}")
#
#     def format_message(self, data):
#         try:
#             message_info = {
#                 "消息ID": data.get("msg_id"),
#                 "发送者": data.get("from_user_name", {}).get("str"),
#                 "接收者": data.get("to_user_name", {}).get("str"),
#                 "消息类型": data.get("msg_type"),
#                 "创建时间": datetime.fromtimestamp(data.get("create_time", 0)).strftime("%Y-%m-%d %H:%M:%S"),
#                 "状态": data.get("status")
#             }
#
#             if "content" in data and isinstance(data["content"], dict) and "str" in data["content"]:
#                 xml_content = data["content"]["str"]
#                 message_info["原始内容"] = xml_content
#
#             return message_info
#         except Exception as e:
#             log.error(f"格式化消息失败: {str(e)}")
#             return data
#
#     async def connect(self):
#         full_url = f"{self.ws_url}?key={self.api_key}"
#         log.info(f"正在连接 WebSocket: {full_url}")
#         self.redis_client = await self.redis_service.get_redis()
#         try:
#             self.websocket_conn = await websockets.connect(full_url,ping_timeout=30, ping_interval=25)
#             log.info("WebSocket 连接已建立")
#             self.is_running = True
#             # 接收消息循环
#             async for message in self.websocket_conn:
#                 await self.on_message(message)
#         except websockets.exceptions.ConnectionClosed as e:
#             log.error(f"WebSocket 连接异常关闭: {e},{e.reason}")
#             self.is_running = False
#             if self.Reconnect_Count < 50:
#                 await asyncio.sleep(self.timt_num)
#                 await self.connect()
#                 self.Reconnect_Count = self.Reconnect_Count + 1
#                 self.timt_num = self.timt_num + 20
#             else:
#                 log.error("WebSocket 连接异常关闭,已经重试5次以上，现在不再重试")
#         except Exception as e:
#             log.error(f"WebSocket 连接异常: {e}，{type(e)}，{e}")
#             self.is_running = False
#
#     def disconnect(self):
#         if self.websocket_conn:
#             asyncio.create_task(self.websocket_conn.close())
#             log.info("存在然后WebSocket 已断开")
#             self.is_running = False
#
#         else:
#             self.is_running = False
#             log.info("WebSocket 已断开")
#
#     def get_status(self):
#         return {
#             "is_running": self.is_running,
#             "ws_url": self.ws_url
#         }
#
